package com.jindy.module.additionalDeposit.service.impl;

import com.jindy.common.constant.Constants;
import com.jindy.common.core.domain.AjaxResult;
import com.jindy.common.core.domain.model.LoginUser;
import com.jindy.common.exception.base.BaseException;
import com.jindy.common.utils.DateUtils;
import com.jindy.common.utils.SecurityUtils;
import com.jindy.common.utils.StringUtils;
import com.jindy.jpush.utils.UniJpushUtils;
import com.jindy.module.additionalDeposit.domain.SyAdditionalDeposit;
import com.jindy.module.additionalDeposit.mapper.SyAdditionalDepositMapper;
import com.jindy.module.additionalDeposit.service.ISyAdditionalDepositService;
import com.jindy.module.approvalConfig.domain.ApprovalConfig;
import com.jindy.module.approvalConfig.mapper.ApprovalConfigMapper;
import com.jindy.module.approvalRecord.domain.ApprovalRecord;
import com.jindy.module.approvalRecord.mapper.ApprovalRecordMapper;
import com.jindy.module.jpush.mapper.JpushMapper;
import com.jindy.module.order.domain.Order;
import com.jindy.module.order.mapper.OrderMapper;
import com.jindy.module.outgoingapproval.service.impl.SyOutgoingApprovalServiceImpl;
import com.jindy.module.serialNum.service.ISySerialNumTService;
import com.jindy.module.statement.domain.AccountStatement;
import com.jindy.module.statement.mapper.AccountStatementMapper;
import com.jindy.module.syTableRecord.service.ISyTableRecordTService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 追加押金申请Service业务层处理
 * 
 * @author jindy
 * @date 2023-05-25
 */
@Service
public class SyAdditionalDepositServiceImpl implements ISyAdditionalDepositService 
{
    private static final Logger LOGGER = LoggerFactory.getLogger(SyOutgoingApprovalServiceImpl.class);

    @Resource
    private SyAdditionalDepositMapper syAdditionalDepositMapper;

    /**
     * 租赁订单Mapper
     */
    @Resource
    private OrderMapper orderMapper;

    /**
     * 结算订单Mapper
     */
    @Resource
    private AccountStatementMapper accountStatementMapper;

    /**
     * 存储表Service
     */
    @Resource
    private ISyTableRecordTService iSyTableRecordTService;

    /**
     * 生成流水单号Service
     */
    @Resource
    private ISySerialNumTService serialNumTService;

    /**
     * 审批记录Service
     */
    @Resource
    private ApprovalRecordMapper approvalRecordMapper;

    /**
     * 审批记录Service
     */
    @Resource
    private ApprovalConfigMapper approvalConfigMapper;

    /**
     * 设备id配置表
     */
    @Resource
    private JpushMapper jpushMapper;

    /**
     * 查询追加押金申请
     * 
     * @param id 追加押金申请主键
     * @return 追加押金申请
     */
    @Override
    public SyAdditionalDeposit selectSyAdditionalDepositById(Long id)
    {
        return syAdditionalDepositMapper.selectSyAdditionalDepositById(id);
    }

    /**
     * 查询追加押金申请列表
     * 
     * @param syAdditionalDeposit 追加押金申请
     * @return 追加押金申请
     */
    @Override
    public List<SyAdditionalDeposit> selectSyAdditionalDepositList(SyAdditionalDeposit syAdditionalDeposit)
    {
        return syAdditionalDepositMapper.selectSyAdditionalDepositList(syAdditionalDeposit);
    }

    /**
     * 新增追加押金申请
     * 
     * @param syAdditionalDeposit 追加押金申请
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertSyAdditionalDeposit(SyAdditionalDeposit syAdditionalDeposit)
    {
        // 获取当前人
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("请先登录");
        }
        // 判断是否再提交
        if (null==syAdditionalDeposit.getId()){
            // 生成流水单号
            String serialNum = serialNumTService.generateSerialNum("ZJYJ");
            if (StringUtils.isBlank(serialNum)) {
                throw new BaseException("新增请假审批-获取外出单号失败");
            }
            syAdditionalDeposit.setCreateTime(DateUtils.getNowDate());
            syAdditionalDeposit.setBusinessStatus(Constants.APPROVE);
            syAdditionalDeposit.setSerialNum(serialNum);
            syAdditionalDepositMapper.insertSyAdditionalDeposit(syAdditionalDeposit);
        }else{
            syAdditionalDeposit.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
            syAdditionalDeposit.setUpdateBy(loginUser.getUsername());
            syAdditionalDeposit.setBusinessStatus(Constants.APPROVE);
            updateSyAdditionalDeposit(syAdditionalDeposit);
            //删除审批记录
            approvalRecordMapper.deleteApprovalRecordBySerialNum(syAdditionalDeposit.getSerialNum());
        }
        iSyTableRecordTService.saveEntityAndTable(syAdditionalDeposit,syAdditionalDeposit.getSerialNum());
        // 新增审批记录
        List<Long> addJpushList= addApprovalRecord(syAdditionalDeposit);
        sendApproveMessage(addJpushList);
        return AjaxResult.success();
    }

    /**
     * 给审批人推送消息
     * @param addJpushList
     */
    private void sendApproveMessage(List<Long> addJpushList) {
        try {
            List<String> addRegIds = jpushMapper.selectRegistrationIdsByUserIds(addJpushList);
            if (!CollectionUtils.isEmpty(addRegIds)){
                UniJpushUtils.sendApproveMessage(addRegIds);
            }
        } catch (Exception e) {
            LOGGER.error("追加押金推送通知失败",e);
        }
    }

    /**
     * 新增审批记录
     * @param syAdditionalDeposit
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public List<Long> addApprovalRecord(SyAdditionalDeposit syAdditionalDeposit) {
        List<Long> list = new ArrayList<>();
        int sequence = 1;
        //  发起人
        ApprovalRecord firstApprovalRecord = getApprovalRecord(syAdditionalDeposit);
        firstApprovalRecord.setSequence(sequence);
        firstApprovalRecord.setApprovalStatus(Constants.COMPLETED);
        firstApprovalRecord.setTypeOperation(Constants.AGREE);
        firstApprovalRecord.setBusinessStatus(Constants.APPROVE);
        firstApprovalRecord.setApproverId(Long.valueOf(syAdditionalDeposit.getApplyUserId()));
        firstApprovalRecord.setApproverName(syAdditionalDeposit.getApplyUserName());
        approvalRecordMapper.insertApprovalRecord(firstApprovalRecord);

        //范雯雯
        sequence++;
        List<ApprovalConfig> approvalConfigList = approvalConfigMapper.selectApprovalConfigList(new ApprovalConfig("ZJYJ-FWW", "1"));
        if (CollectionUtils.isEmpty(approvalConfigList)) {
            throw new RuntimeException("请检查审批配置信息：ZJYJ-FWW");
        }
        list.add(approvalConfigList.get(0).getUserId());
        addApprovalConfig(sequence, approvalConfigList,syAdditionalDeposit);

        return list;
    }
    /**
     * 新增第二，第三审批记录信息
     *
     * @param sequence
     * @param approvalConfigList
     */
    @Transactional(rollbackFor = Exception.class)
    public void addApprovalConfig(int sequence, List<ApprovalConfig> approvalConfigList, SyAdditionalDeposit syAdditionalDeposit) {
        String status = Constants.NOT_APPROVED;
        if (sequence == 2) {
            status = Constants.APPROVE;
        }
        for (ApprovalConfig approvalConfig : approvalConfigList) {
            ApprovalRecord approvalRecord = getApprovalRecord(syAdditionalDeposit);
            approvalRecord.setSequence(sequence);
            approvalRecord.setApprovalStatus(status);
            approvalRecord.setApproverId(approvalConfig.getUserId());
            approvalRecord.setApproverName(approvalConfig.getUsername());
            approvalRecordMapper.insertApprovalRecord(approvalRecord);
        }
    }

    /**
     * 获取审批记录对象
     *
     * @param syAdditionalDeposit
     * @return
     */
    private ApprovalRecord getApprovalRecord(SyAdditionalDeposit syAdditionalDeposit) {
        ApprovalRecord approvalRecord = new ApprovalRecord();
        approvalRecord.setSerialNum(syAdditionalDeposit.getSerialNum());
        approvalRecord.setUserId(Long.valueOf(syAdditionalDeposit.getApplyUserId()));
        approvalRecord.setOrderId(syAdditionalDeposit.getId());
        approvalRecord.setUserName(syAdditionalDeposit.getApplyUserName());
        approvalRecord.setUpdateTime(DateUtils.parseDate(DateUtils.getTime()));
        approvalRecord.setUpdateBy(syAdditionalDeposit.getApplyUserName());
        approvalRecord.setCreateBy(syAdditionalDeposit.getApplyUserName());
        approvalRecord.setCreateTime(DateUtils.parseDate(DateUtils.getTime()));
        return approvalRecord;
    }

    /**
     * 修改追加押金申请
     * 
     * @param syAdditionalDeposit 追加押金申请
     * @return 结果
     */
    @Override
    public int updateSyAdditionalDeposit(SyAdditionalDeposit syAdditionalDeposit)
    {
        syAdditionalDeposit.setUpdateTime(DateUtils.getNowDate());
        return syAdditionalDepositMapper.updateSyAdditionalDeposit(syAdditionalDeposit);
    }

    /**
     * 批量删除追加押金申请
     * 
     * @param ids 需要删除的追加押金申请主键
     * @return 结果
     */
    @Override
    public int deleteSyAdditionalDepositByIds(Long[] ids)
    {
        return syAdditionalDepositMapper.deleteSyAdditionalDepositByIds(ids);
    }

    /**
     * 删除追加押金申请信息
     * 
     * @param id 追加押金申请主键
     * @return 结果
     */
    @Override
    public int deleteSyAdditionalDepositById(Long id)
    {
        return syAdditionalDepositMapper.deleteSyAdditionalDepositById(id);
    }

    /**
     * 审批同意之后，租赁单或结算单追加押金
     * @param serialNum
     */
    public void addToDeposit(String serialNum){
    //    1. 根据流水单号，获取追加押金信息
        SyAdditionalDeposit ad = syAdditionalDepositMapper.selectSyAdditionalDepositBySerialNum(serialNum);
        if (Objects.isNull(ad)){
            throw new BaseException("获取追加押金信息为空");
        }
    //  2. 获取类型：租赁单/销售 or 结算单
        String type = ad.getType();
        //    追加押金
        BigDecimal additionalAccount = null==ad.getAdditionalAccount()?BigDecimal.ZERO: ad.getAdditionalAccount();
        if ("1".equals(type)){
        //    租赁单/销售
            Order order = orderMapper.selectOrderByOrderNo(ad.getOrderNo());
            if (Objects.isNull(order)){
                throw new BaseException("开票申请-"+ad.getOrderNo()+"租赁订单不存在");
            }
            //实收押金
            BigDecimal receivedAmount = null==order.getReceivedAmount()?BigDecimal.ZERO:order.getReceivedAmount();

            BigDecimal newReceivedAmount = receivedAmount.add(additionalAccount);
            order.setReceivedAmount(newReceivedAmount);
            orderMapper.updateOrder(order);
        }else{
        //    结算单
            AccountStatement accountStatement = accountStatementMapper.selectAccountStatementByNumber(serialNum);
            if (Objects.isNull(accountStatement)){
                throw new BaseException("开票申请-"+ad.getOrderNo()+"结算单不存在");
            }
            //实收押金
            BigDecimal depositPaid = null==accountStatement.getDepositPaid()?BigDecimal.ZERO:accountStatement.getDepositPaid();
            BigDecimal newDepositPaid = depositPaid.add(additionalAccount);
            accountStatement.setDepositPaid(newDepositPaid);
            accountStatementMapper.updateAccountStatement(accountStatement);
        }
    }
}
